package mixlog

import (
	"fmt"
	"io"
	"os"

	rotatelogs "github.com/lestrrat-go/file-rotatelogs"
	"github.com/mattn/go-colorable"
)

// handler 日志处理器
type handler struct {
	// Lvl 日志等级
	Lvl Lvl

	// Writer 日志写入接口
	Writer io.Writer

	// DisableColor 关闭颜色
	DisableColor bool

	// Formatter 格式化器
	Formatter *formatter
}

// writeLog 先将一条日志格式化，然后写入接口
func (h *handler) writeLog(entry entry) {
	if entry.lvlNo >= h.Lvl {
		logStr := h.Formatter.logFormat(entry)

		var err error
		if !h.DisableColor {
			if fd, ok := h.Writer.(*os.File); ok {
				colorFd := colorable.NewColorable(fd) // 对于windows将使用colorable进行包装，其它系统直接返回
				_, err = LvlColorMap[entry.lvlNo].Fprintf(colorFd, logStr)
			}
		} else {
			_, err = h.Writer.Write([]byte(logStr))
		}

		if err != nil {
			_, _ = fmt.Fprintf(os.Stderr, err.Error())
		}
	}
}

// NewHandlerToWriter 创建一个 handler，日志写入到 io.Writer
func NewHandlerToWriter(lvl Lvl, formatter *formatter, w io.Writer, disableColor bool) *handler {
	return &handler{lvl, w, disableColor, formatter}
}

// NewHandlerToFile 创建一个 handler，日志写入到指定的文件
func NewHandlerToFile(lvl Lvl, formatter *formatter, logfile string, doTrunc bool) (*handler, error) {
	var (
		f   *os.File
		err error
	)
	if doTrunc {
		f, err = os.OpenFile(logfile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
	} else {
		f, err = os.OpenFile(logfile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
	}
	if err != nil {
		return nil, err
	}
	return NewHandlerToWriter(lvl, formatter, f, true), nil
}

// MustNewHandlerToFile 创建一个 handler，日志写入到指定的文件
func MustNewHandlerToFile(lvl Lvl, formatter *formatter, logfile string, doTrunc bool) *handler {
	h, err := NewHandlerToFile(lvl, formatter, logfile, doTrunc)
	if err != nil {
		panic(err)
	}
	return h
}

// NewHandlerToRotateLogs 创建一个 handler，日志写入到 `*rotatelogs.RotateLogs`
// rotatelogs 是一个的滚动日志包，地址：https://github.com/lestrrat-go/file-rotatelogs
func NewHandlerToRotateLogs(lvl Lvl, formatter *formatter, r *rotatelogs.RotateLogs) *handler {
	return NewHandlerToWriter(lvl, formatter, r, true)
}
